const path = require('path');

const merge = require('webpack-merge');

const EX = require('extract-text-webpack-plugin');
const HM = require('html-webpack-plugin');
const CLEAR = require('clean-webpack-plugin');
const WP = require('webpack');

const DevConfig = require('./webpack.dev.conf');
const ProdConfig = require('./webpack.prod.conf');
// 这里改造成函数是因为需要loader根据不同环境上不同loader
const BaseConfig = env => { 

    // 提取css 生产环境
    const ExtractTextWebpackPlugin = new EX({
        filename: 'assets/css/[name]-bundle-[hash:5].css'
    });

    // 提取loader
    const FileLoader = [
        {
            test: /\.(png|jpg|jpeg)$/,
            use: [{
                loader: 'file-loader',
                options: {
                    outputPath: 'assets/img/',
                    filename: '[name]-[hash].[ext]'
                }
            }]
        }
    ];
    const ScriptLoader = [
        // babel
        {
            test: /\.js$/,
            use: [{
                loader: 'babel-loader'
                // 配置移植到.babelrc中
            }].concat( env == 'dev' ? [
                // 根据环境判断是否加eslint
                // 开发环境需要加一下
                {
                    loader: 'eslint-loader',
                    options: {
                        // 使用我们安装的eslit formatter 它可以更友好的标注出哪里有问题。
                        formatter: require('eslint-friendly-formatter')
                    }
                }
            ] : [
                // 生产环境不需要eslint
            ])
        }
    ];
    const StyleLoader = [].concat( env == 'dev' ? [
    // less
    {
        test: /\.(less|css)$/,
        use: [
            {
                loader: 'style-loader'
            },{
                loader: 'css-loader'
            },{
                loader: 'less-loader'
            }
        ]
    }
    ]:[
        {   
            test: /\.(less|css)$/,
            use: EX.extract({
                // 异步的加载走这个
                fallback: {
                    loader: 'style-loader'
                },
                use: [{
                    loader: 'css-loader'
                },{
                    loader: 'less-loader'
                }]
            })
        }
    ]);

    return {
        // entry
        entry: {
            idx: ['webpack-hot-middleware/client.js', path.resolve(__dirname, 'src/idx.js')]
        },
        // output
        output: {
            path: path.resolve(__dirname, 'dist/'),
            filename: '[name].[hash].js',
            publicPath: '/'
        },
        // resolve
        resolve: {
            alias: {
                // 项目中引入使用
                // import 'assets/idx.css';
                // import $ from 'jquery';
                // import 'key/路径';

                // 资源目录
                assets: path.resolve(__dirname, 'src/assets'),
                // 资源文件 末尾需要加$代表确切的文件
                jquery$: path.resolve(__dirname, 'src/lib/jquery.js')
            }
        },
        module: {
            rules: ScriptLoader.concat(StyleLoader).concat(FileLoader)
        },
        plugins: [
            // 无论生产还是开发都会用到的
            new HM({
                filename: 'index.html',
                template: path.resolve(__dirname, './index.html'),
                minify: {
                    collapseWhitespace: true
                }
            }),
            new CLEAR('dist'),
            new WP.ProvidePlugin({
                // 全局注入不用再import
                $: 'jquery' // 来自resolve alias
            }),
        ].concat(env == 'dev' ? [
            new WP.HotModuleReplacementPlugin(),
            new WP.NamedModulesPlugin()
        ] : [ExtractTextWebpackPlugin])
    }
}

// webpack 读取配置进入回调，借助webpack merge 撮合配置文件 env是package.json执行脚本传进来的env
module.exports = (env) => {
    const config = env == 'dev' ? DevConfig : ProdConfig;
    
    // 返回撮合后的配置文件。后面的同key配置会覆盖前面的配置。和不同的环境配置文件撮合
    return merge(BaseConfig(env), config);
}